package br.unicamp.ic.inf312.arena.persistencia.dao.impl;

import java.sql.Time;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import br.unicamp.ic.inf312.arena.modelo.artistico.Espetaculo;
import br.unicamp.ic.inf312.arena.modelo.financeiro.ContaContabil;
import br.unicamp.ic.inf312.arena.modelo.logistico.Evento;
import br.unicamp.ic.inf312.arena.modelo.logistico.Sala;
import br.unicamp.ic.inf312.arena.modelo.logistico.UnidadeNegocio;
import br.unicamp.ic.inf312.arena.modelo.pessoa.Funcionario;
import br.unicamp.ic.inf312.arena.persistencia.dao.IEspetaculoDAO;
import br.unicamp.ic.inf312.arena.persistencia.dao.IEventoDAO;
import br.unicamp.ic.inf312.arena.persistencia.dao.ISalaDAO;
import br.unicamp.ic.inf312.framework.persistencia.DataAccessObjectFactory;
import br.unicamp.ic.inf312.framework.persistencia.SQLUtil;

public class EventoDAOMySQL implements IEventoDAO {

	/**
	 * 
	 */
	public Collection<Evento> obterEventosEmCartaz(String strDataInicio,
			String strDataTermino, boolean haVagas) throws Exception {

		ArrayList<Evento> eventos = null;
		if (strDataInicio != null && strDataTermino != null) {
			if (!"".equals( strDataInicio )
					&& !"".equals( strDataTermino )) {		
		
				System.out.println("\nstrDataInicio = " + strDataInicio
						+ " strDataTermino = " + strDataTermino);
				//
				StringBuffer stbQuery = new StringBuffer();
				stbQuery.append(" SELECT ");
				//cols. 0 a 3
				stbQuery.append("   ev.codevento, ev.data, ev.horariosessao, ev.qtdvagaslivre, ");
				//cols. 4 a 6
				stbQuery.append("   ev.valor, ev.codespetaculo, es.tipo, ");
				//cols. 7 a 11
				stbQuery.append("   ev.codsala, s.tipo, s.codunidade, u.codconta, cc.numcartaocredito ");
				stbQuery.append(" FROM ");
				stbQuery.append("   evento ev, espetaculo es, sala s, unidade_negocio u, ");
				stbQuery.append("   conta_contabil cc ");
				stbQuery.append(" WHERE ");
				stbQuery.append("   ev.codespetaculo = es.codespetaculo AND ");
				stbQuery.append("   ev.codsala = s.codsala  AND ");
				stbQuery.append("   s.codunidade = u.codunidade  AND ");
				stbQuery.append("   u.codconta = cc.codconta  AND ");
				stbQuery.append("   ev.data >= ? AND ");
				stbQuery.append("   ev.data <= ? ");

				//
				int qtdVagasLivre = 0;
				Object[] params   = null;
				if(haVagas) {
					stbQuery.append(" AND ev.qtdvagaslivre > ? ");

					params = new Object[3];
					params[0] = java.sql.Date.valueOf(strDataInicio);
					params[1] = java.sql.Date.valueOf(strDataTermino);
					params[2] = qtdVagasLivre;
				} else {
					params = new Object[2];
					params[0] = java.sql.Date.valueOf(strDataInicio);
					params[1] = java.sql.Date.valueOf(strDataTermino);
				}
				stbQuery.append(" ORDER BY ev.data, ev.horariosessao, ev.qtdvagaslivre ASC ");

				Evento evento = null;
				ArrayList result  = null;
				eventos = new ArrayList<Evento>();

				//selectRecordS
				result = (ArrayList) SQLUtil.selectRecordS(stbQuery.toString(), params);
				if (result != null && result.size() > 0) {
					int codSala       = 0;
					int codEspetaculo = 0;
					int tipoEspetaculo = 0;
					Sala sala = null;
					Espetaculo espetaculo = null;

					//
					IEspetaculoDAO daoEspetaculo = null;
					daoEspetaculo = (IEspetaculoDAO) DataAccessObjectFactory
						.getImpl(IEspetaculoDAO.class);

					ISalaDAO daoSala = null;
					daoSala = (ISalaDAO) DataAccessObjectFactory
						.getImpl(ISalaDAO.class);

					// itera sobre o resultado da base populando Evento, inclusive com
					// Espetaculo, Sala, UnidadeNegocio e ContaContabil
					for (Iterator iter = result.iterator(); iter.hasNext();) {
						Object[] record = (Object[]) iter.next();
						//
						if (record != null && record.length > 0) {
							evento = new Evento();
							evento.setCodEvento( ((Long) record[0]).longValue() );
							evento.setData( (java.sql.Date) record[1] );
							evento.setHorarioSessao( (Time) record[2] );
							evento.setQtdVagasLivre( ((Integer) record[3]).intValue() );
							evento.setValor( ((Double) record[4]).doubleValue() );
							//FK - Espetaculo
							codEspetaculo  = ((Integer) record[5]).intValue();
							tipoEspetaculo = ((Integer) record[6]).intValue();

							espetaculo = daoEspetaculo.obterEspetaculo(codEspetaculo,
									tipoEspetaculo);
							evento.setEspetaculo(espetaculo);

							//FK - Sala
							codSala = ((Integer) record[7]).intValue();
							int tipoSala = ((Integer) record[8]).intValue(); 

							sala = daoSala.obterSala(codSala, tipoSala);
							evento.setSala(sala); //Evento x Sala

							//s.codunidade, u.codconta, cc.numcartaocredito
							int codUnidade = ((Integer) record[9]).intValue();
							int codConta = ((Integer) record[10]).intValue();
							long numCartaoConta = ((Long) record[11]).longValue();

							//TODO: Alteracao para a ativ. 5
							ContaContabil contaContabil = this.getContaContabil(codConta);
							
							//TODO: Alteracao para a ativ. 5
							UnidadeNegocio unidade = this.getUnidadeNegocio(codUnidade);
							unidade.setContaContabil(contaContabil); //UnidadeNegocio x ContaContabil

							sala.setUnidadeNegocio(unidade); //Sala x UnidadeNegocio

							//
							eventos.add(evento);
						}
					}
				}
			}
		}
		return eventos;
	}

	/**
	 * Atualiza qtdVagasLivres conforme param. qtd do Espetaculo associado a PK codigo
	 * 
	 * @param codigo
	 * @param qtd
	 * 
	 * @return int
	 * 
	 * @throws Exception
	 */
	public int atualizar(long codigo, int qtd) throws Exception {
		int result = 0;
		Object[] params = new Object[2];
		params[0] = qtd;
		params[1] = codigo;

		StringBuffer stbQuery = new StringBuffer();
		stbQuery.append(" UPDATE ");
		stbQuery.append(SQLUtil.getDbSchema() + "." + IEventoDAO.TABELA_BD
				+ " SET ");
		stbQuery.append(IEventoDAO.COLUMN_QTD_VAGAS_LIVRES + " = ? ");
		stbQuery.append(" WHERE " + IEventoDAO.COLUMN_CODIGO_PK + " = ? ");
		//
		result = SQLUtil.update(stbQuery.toString(), params);
		return result;
	}
	
	//TODO: Alteracao para a ativ. 5
	private UnidadeNegocio getUnidadeNegocio( int codUnidade ) throws Exception
	{
		return ((UnidadeNegocio) SQLUtil.retrieveBean( "SELECT * from unidade_negocio WHERE codunidade = ?", UnidadeNegocio.class, new Object[]{ codUnidade } ));
	}
	
	//TODO: Alteracao para a ativ. 5
	private ContaContabil getContaContabil( int codConta ) throws Exception
	{
		return ((ContaContabil) SQLUtil.retrieveBean( "SELECT * from conta_contabil WHERE codconta = ?", ContaContabil.class, new Object[]{ codConta } ));
	}
}